﻿namespace DimensionsHelper.LanguageService.Symbols;

/// <summary>
///     项目范围的符号表。
/// </summary>
public sealed class WorkFolderSymbolTable : SymbolTable
{
    private readonly DeclaredSymbolTable _declaredSymbols = new();

    private readonly SourceSymbolTable _preDefinedMacros = new();

    // 此处用作元数据定义符号表
    protected override Dictionary<string, ISymbol> Symbols { get; } = new(StringComparer.OrdinalIgnoreCase);


    internal DeclaredSymbolTable GetDeclaredSymbols()
    {
        return _declaredSymbols;
    }


    /// <summary>
    ///     预定义宏符号。此符号表和本地符号表不冲突，如果本地符号表带有同名宏符号，以本地符号表为准。
    /// </summary>
    /// <param name="macro">宏符号</param>
    public void PreDefineMacro(MacroSymbol macro)
    {
        _preDefinedMacros.DeclareSymbol(macro);
    }


    /// <summary>
    ///     查找指定名称的预定义宏符号。
    /// </summary>
    /// <param name="name">宏名，大小写敏感</param>
    /// <returns>查找到的符号，如果不存在，返回<see langword="null" /></returns>
    public MacroSymbol? LookupPreDefinedMacro(string name)
    {
        return _preDefinedMacros.LookupLocalSymbol(name) as MacroSymbol;
    }


    /// <summary>
    ///     清空宏预定义表
    /// </summary>
    public void ClearPreDefinedMacros()
    {
        _preDefinedMacros.Clear();
    }


    /// <summary>
    ///     声明项目范围内的元数据符号。
    /// </summary>
    /// <param name="metadataSymbol">元数据符号</param>
    /// <returns>如果声明失败，返回<see langword="false" /></returns>
    public bool DeclareMetadataSymbol(MetadataSymbol metadataSymbol)
    {
        if (Symbols.TryGetValue(metadataSymbol.Name, out ISymbol? symbol))
        {
            return symbol.Redeclare(metadataSymbol);
        }

        Symbols.Add(metadataSymbol.Name, metadataSymbol);
        return true;
    }


    /// <summary>
    ///     查找本地元数据符号。
    /// </summary>
    /// <param name="name">元数据字段名</param>
    public ISymbol? LookupMetadataSymbol(string name)
    {
        return Symbols.GetValueOrDefault(name);
    }


    /// <summary>
    ///     声明项目范围的语法声明符号。
    /// </summary>
    /// <param name="symbol">本地声明符号</param>
    /// <remarks>本地声明符号和全局声明符号冲突，和本地符号表不冲突</remarks>
    public bool DeclareProjectDeclarationSymbol(ISymbol symbol)
    {
        return !GlobalSymbols.TryGetDeclaredSymbol(symbol.FullName, out _) &&
               _declaredSymbols.DeclareSymbol(symbol);
    }


    // 项目范围没有本地定义表 
    protected override bool DeclareSymbolCore(ISymbol symbol)
    {
        return false;
    }


    // 项目范围没有本地定义表 
    protected override ISymbol? LookupSymbolLocalCore(string symbolName)
    {
        return null;
    }


    protected override ISymbol? LookupSymbolDeclareCore(string[] qualifiedName)
    {
        return _declaredSymbols.LookupDeclaredSymbol(qualifiedName);
    }


    public override void Join(ReadOnlySymbolTable table)
    {
        throw new NotSupportedException();
    }
}